Skip to content

Commit

Permalink
Merge 2164751 into ae9fe70
Browse files Browse the repository at this point in the history
  • Loading branch information
angelcervera committed Nov 12, 2020
2 parents ae9fe70 + 2164751 commit 58645b5
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
package com.acervera.osm4scala

import com.acervera.osm4scala.model.NodeEntity
import com.acervera.osm4scala.utilities.StringTableUtils
import org.openstreetmap.osmosis.osmbinary.osmformat.{DenseNodes, StringTable}

object DenseNodesIterator {
Expand All @@ -50,7 +51,7 @@ class DenseNodesIterator(osmosisStringTable: StringTable,
latOffset: Long = 0,
lonOffset: Long = 0,
granularity: Int = 100)
extends Iterator[NodeEntity] {
extends Iterator[NodeEntity] with StringTableUtils {

if (osmosisDenseNode.denseinfo.isDefined && osmosisDenseNode.denseinfo.get.visible.nonEmpty) {
throw new Exception("Only visible nodes are implemented.")
Expand All @@ -72,18 +73,14 @@ class DenseNodesIterator(osmosisStringTable: StringTable,
decompressCoord(latOffset, latIterator.next(), lastNode.latitude)
val longitude =
decompressCoord(lonOffset, lonIterator.next(), lastNode.longitude)
val tags = tagsIterator
.takeWhile(_ != 0L)
.grouped(2)
.map { tag =>
osmosisStringTable.s(tag.head).toString("UTF-8") -> osmosisStringTable
.s(tag.last)
.toString("UTF-8")
}
.toMap

// Create node
lastNode = NodeEntity(id, latitude, longitude, tags)
lastNode = NodeEntity(
id,
latitude,
longitude,
osmosisStringTable.extractTags(tagsIterator.takeWhile(_ != 0L))
)

lastNode
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

package com.acervera.osm4scala.model

import com.acervera.osm4scala.utilities.StringTableUtils
import org.openstreetmap.osmosis.osmbinary.osmformat.{Relation, StringTable}

/**
Expand All @@ -36,24 +37,23 @@ case class RelationEntity(id: Long, relations: Seq[RelationMemberEntity], tags:

}

object RelationEntity {
object RelationEntity extends StringTableUtils {

def apply(osmosisStringTable: StringTable, osmosisRelation: Relation): RelationEntity = {

// Calculate tags using the StringTable.
val tags = (osmosisRelation.keys, osmosisRelation.vals).zipped.map { (k, v) =>
osmosisStringTable.s(k).toString("UTF-8") -> osmosisStringTable.s(v).toString("UTF-8")
}.toMap

// Decode members references in stored in delta compression.
val members = osmosisRelation.memids.scanLeft(0L) { _ + _ }.drop(1)

// Calculate relations
val relations = (members, osmosisRelation.types, osmosisRelation.rolesSid).zipped.map { (m, t, r) =>
RelationMemberEntity(m, RelationMemberEntityTypes(t.value), osmosisStringTable.s(r).toString("UTF-8"))
RelationMemberEntity(m, RelationMemberEntityTypes(t.value), osmosisStringTable.getString(r))
}

new RelationEntity(osmosisRelation.id, relations, tags)
new RelationEntity(
osmosisRelation.id,
relations,
osmosisStringTable.extractTags(osmosisRelation.keys, osmosisRelation.vals)
)
}

}
14 changes: 7 additions & 7 deletions core/src/main/scala/com/acervera/osm4scala/model/WayEntity.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

package com.acervera.osm4scala.model

import com.acervera.osm4scala.utilities.StringTableUtils
import org.openstreetmap.osmosis.osmbinary.osmformat.{StringTable, Way}

/**
Expand All @@ -40,19 +41,18 @@ case class WayEntity(id: Long, nodes: Seq[Long], tags: Map[String, String]) exte

}

object WayEntity {
object WayEntity extends StringTableUtils {

def apply(osmosisStringTable: StringTable, osmosisWay: Way): WayEntity = {

// Calculate nodes references in stored in delta compression.
val nodes = osmosisWay.refs.scanLeft(0L) { _ + _ }.drop(1)

// Calculate tags using the StringTable.
val tags = (osmosisWay.keys, osmosisWay.vals).zipped.map { (k, v) =>
osmosisStringTable.s(k).toString("UTF-8") -> osmosisStringTable.s(v).toString("UTF-8")
}.toMap

new WayEntity(osmosisWay.id, nodes, tags)
new WayEntity(
osmosisWay.id,
nodes,
osmosisStringTable.extractTags(osmosisWay.keys, osmosisWay.vals)
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Ángel Cervera Claudio
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

package com.acervera.osm4scala.utilities

import org.openstreetmap.osmosis.osmbinary.osmformat.StringTable

/**
* Utilities to extract data from StringTable Objects.
*/
private[osm4scala] trait StringTableUtils {

private val CHARSET = "UTF-8"

implicit class StringTableEnricher(stringTable: StringTable) {

/**
* From a sequence of keys and values indexes, it creates a Map of tags.
*
* @param keys Sequence of indexes pointing to strings used as keys
* @param values Sequence of indexes pointing to strings used as values
* @return Map with tags.
*/
def extractTags(keys: Seq[Int], values: Seq[Int]): Map[String, String] =
(keys, values).zipped.map { (key, value) =>
stringTable.s(key).toString(CHARSET) -> stringTable.s(value).toString(CHARSET)
}.toMap

/**
* From a sequence of indexes following the sequence pattern `(key,value)*`, it creates a Map of tags.
*
* @param keyValueSequence key,value sequence.
* @return Map with tags.
*/
def extractTags(keyValueSequence: Iterator[Int]): Map[String, String] =
keyValueSequence
.grouped(2)
.map(tag => stringTable.s(tag.head).toString(CHARSET) -> stringTable.s(tag.last).toString(CHARSET))
.toMap

/**
* Extract String from the String table.
*
* @param idx String index.
* @return Proper Scala String.
*/
def getString(idx: Int): String = stringTable.s(idx).toString(CHARSET)

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2017 Ángel Cervera Claudio
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

package com.acervera.osm4scala.utilities

import com.google.protobuf.ByteString
import org.openstreetmap.osmosis.osmbinary.osmformat.StringTable
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike

class StringTableUtilsSpec extends AnyWordSpecLike with Matchers with StringTableUtils {

val strTable = StringTable(
(0 to 10).map(idx => ByteString.copyFromUtf8(s"value$idx"))
)

"StringTableEnricher" should {
"extract tags from one sequences of keys and other of values " in {
strTable.extractTags(Seq(0,5), Seq(2,1)) shouldBe Map(
"value0" -> "value2",
"value5" -> "value1"
)
}
"extract tags from key,value sequence" in {
strTable.extractTags(Seq(0,2,5,1).toIterator) shouldBe Map(
"value0" -> "value2",
"value5" -> "value1"
)
}
"extract the String" in {
strTable.getString(0) shouldBe "value0"
}
}

}

0 comments on commit 58645b5

Please sign in to comment.