Skip to content

Commit 16bffa7

Browse files
authored
Feauture/#40 info fields (#87)
close #40
1 parent 3e21075 commit 16bffa7

File tree

61 files changed

+1411
-7177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1411
-7177
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
target
33
core/src/pbf_generated/
44
project/project/
5+
tmp

README.md

-4
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,3 @@ export GIT_USER=<username>; export USE_SSH=true; npm run deploy
5757

5858
### third party OSS libraries:
5959
- ScalaPB: https://scalapb.github.io/ and https://github.com/thesamet/sbt-protoc
60-
61-
62-
```
63-

build.sbt

+19-7
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ lazy val commonIOVersion = "2.5"
1111
lazy val logbackVersion = "1.1.7"
1212
lazy val scoptVersion = "3.7.1"
1313
lazy val akkaVersion = "2.5.31"
14-
lazy val spark3Version = "3.0.1"
14+
lazy val spark3Version = "3.1.1"
1515
lazy val spark2Version = "2.4.7"
1616
lazy val sparkDefaultVersion = spark3Version
1717

18-
lazy val scala213 = "2.13.3"
19-
lazy val scala212 = "2.12.12"
18+
lazy val scala213 = "2.13.5"
19+
lazy val scala212 = "2.12.13"
2020
lazy val scala211 = "2.11.12"
2121
lazy val scalaVersions = if (isPatch211Enable()) Seq(scala211) else Seq(scala213, scala212)
2222
lazy val sparkScalaVersions = if (isPatch211Enable()) Seq(scala211) else Seq(scala212)
2323

2424
lazy val commonSettings = Seq(
2525
crossScalaVersions := scalaVersions,
2626
organization := "com.acervera.osm4scala",
27-
organizationHomepage := Some(url("http://www.acervera.com")),
28-
licenses += ("MIT", url("http://opensource.org/licenses/MIT")),
27+
organizationHomepage := Some(url("https://www.acervera.com")),
28+
licenses += ("MIT", url("https://opensource.org/licenses/MIT")),
2929
homepage in ThisBuild := Some(
3030
url(s"https://simplexspatial.github.io/osm4scala/")
3131
),
@@ -116,7 +116,7 @@ def generateSparkModule(sparkVersion: String): Project = {
116116
def pathFromModule(relativePath: String): String = if (sparkDefaultVersion == sparkVersion) {
117117
relativePath
118118
} else {
119-
s"../../spark/${relativePath}"
119+
s"../../spark/$relativePath"
120120
}
121121

122122
Project(id = s"spark${sparkVersion.head}", base = file(baseFolder))
@@ -169,6 +169,8 @@ def listOfProjects(): Seq[ProjectReference] = {
169169
examplesCounterAkka,
170170
examplesTagsExtraction,
171171
examplesPrimitivesExtraction,
172+
examplesBlocksExtraction,
173+
examplesTakeN
172174
)
173175

174176
val spark3Projects: Seq[ProjectReference] = Seq(
@@ -180,7 +182,7 @@ def listOfProjects(): Seq[ProjectReference] = {
180182

181183
val projects = modules ++ (if(isPatch211Enable()) Seq.empty else spark3Projects)
182184

183-
print(s"PATCH_211 is ${isPatch211Enable()} so we are going to work with this list of projects: \n${projects.mkString("\t- ", "\n\t- ", "")}")
185+
println(s"PATCH_211 is ${isPatch211Enable()} so we are going to work with this list of projects: \n${projects.mkString("\t- ", "\n\t- ", "")}")
184186

185187
projects
186188
}
@@ -293,6 +295,16 @@ lazy val examplesBlocksExtraction = Project(id = "examples-blocks-extraction", b
293295
)
294296
.dependsOn(core, commonUtilities)
295297

298+
lazy val examplesTakeN = Project(id = "examples-takeN", base = file("examples/takeN"))
299+
.disablePlugins(AssemblyPlugin)
300+
.settings(
301+
commonSettings,
302+
exampleSettings,
303+
name := "osm4scala-examples-takeN",
304+
description := "Generate a pbf file by taking the first N blocks."
305+
)
306+
.dependsOn(core, commonUtilities)
307+
296308
lazy val examplesPrimitivesExtraction =
297309
Project(id = "examples-primitives-extraction", base = file("examples/primitivesextraction"))
298310
.disablePlugins(AssemblyPlugin)

core/src/main/scala/com/acervera/osm4scala/DenseNodesIterator.scala

+101-16
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@
2525

2626
package com.acervera.osm4scala
2727

28-
import com.acervera.osm4scala.model.NodeEntity
29-
import com.acervera.osm4scala.utilities.StringTableUtils
30-
import org.openstreetmap.osmosis.osmbinary.osmformat.{DenseNodes, StringTable}
28+
import com.acervera.osm4scala.model.{Info, NodeEntity}
29+
import com.acervera.osm4scala.utilities.StringTableUtils._
30+
import org.openstreetmap.osmosis.osmbinary.osmformat.{DenseInfo, DenseNodes, StringTable}
31+
32+
import java.time.Instant
3133

3234
object DenseNodesIterator {
3335

@@ -51,7 +53,7 @@ class DenseNodesIterator(osmosisStringTable: StringTable,
5153
latOffset: Long = 0,
5254
lonOffset: Long = 0,
5355
granularity: Int = 100)
54-
extends Iterator[NodeEntity] with StringTableUtils {
56+
extends Iterator[NodeEntity] {
5557

5658
if (osmosisDenseNode.denseinfo.isDefined && osmosisDenseNode.denseinfo.get.visible.nonEmpty) {
5759
throw new Exception("Only visible nodes are implemented.")
@@ -61,28 +63,31 @@ class DenseNodesIterator(osmosisStringTable: StringTable,
6163
private val lonIterator = osmosisDenseNode.lon.iterator
6264
private val latIterator = osmosisDenseNode.lat.iterator
6365
private val tagsIterator = osmosisDenseNode.keysVals.iterator
66+
private val infoIterator = InfoIterator(osmosisDenseNode.denseinfo)
6467

65-
private var lastNode: NodeEntity = NodeEntity(0, 0, 0, Map())
68+
// Delta references
69+
var lastId = 0L
70+
var lastLatitude = 0.0
71+
var lastLongitude = 0.0
6672

6773
override def hasNext: Boolean = idIterator.hasNext
6874

6975
override def next(): NodeEntity = {
7076

71-
val id = idIterator.next() + lastNode.id
72-
val latitude =
73-
decompressCoord(latOffset, latIterator.next(), lastNode.latitude)
74-
val longitude =
75-
decompressCoord(lonOffset, lonIterator.next(), lastNode.longitude)
77+
// Calculate new values base in deltas and update deltas
78+
lastId = idIterator.next() + lastId
79+
lastLatitude = decompressCoord(latOffset, latIterator.next(), lastLatitude)
80+
lastLongitude = decompressCoord(lonOffset, lonIterator.next(), lastLongitude)
7681

7782
// Create node
78-
lastNode = NodeEntity(
79-
id,
80-
latitude,
81-
longitude,
82-
osmosisStringTable.extractTags(tagsIterator.takeWhile(_ != 0L))
83+
NodeEntity(
84+
lastId,
85+
lastLatitude,
86+
lastLongitude,
87+
osmosisStringTable.extractTags(tagsIterator.takeWhile(_ != 0L)),
88+
infoIterator.next()
8389
)
8490

85-
lastNode
8691
}
8792

8893
/**
@@ -97,4 +102,84 @@ class DenseNodesIterator(osmosisStringTable: StringTable,
97102
(.000000001 * (offSet + (granularity * delta))) + currentValue
98103
}
99104

105+
// Decode DenseInfo
106+
107+
trait InfoIterator extends Iterator[Option[Info]]
108+
109+
class InfoIteratorDeltas(denseInfo: DenseInfo) extends InfoIterator {
110+
val versionIterator = denseInfo.version.iterator
111+
val timestampIterator = denseInfo.timestamp.iterator
112+
val changesetIterator = denseInfo.changeset.iterator
113+
val uidIterator = denseInfo.uid.iterator
114+
val userNameIterator = denseInfo.userSid.iterator
115+
val visibleIterator = denseInfo.visible.iterator
116+
117+
var lastTimestamp = 0L
118+
var lastChangeset = 0L
119+
var lastUserId = 0
120+
var lastUserName = 0
121+
122+
override def hasNext: Boolean =
123+
versionIterator.hasNext ||
124+
timestampIterator.hasNext ||
125+
changesetIterator.hasNext ||
126+
uidIterator.hasNext ||
127+
userNameIterator.hasNext ||
128+
visibleIterator.hasNext
129+
130+
override def next(): Option[Info] = {
131+
132+
val newTimestamp = if (timestampIterator.hasNext) {
133+
lastTimestamp = lastTimestamp + timestampIterator.next()
134+
Some(Instant.ofEpochSecond(lastTimestamp))
135+
} else {
136+
None
137+
}
138+
139+
val newChangeset = if (changesetIterator.hasNext) {
140+
lastChangeset = lastChangeset + changesetIterator.next()
141+
Some(lastChangeset)
142+
} else {
143+
None
144+
}
145+
146+
val newUserId = if (uidIterator.hasNext) {
147+
lastUserId = lastUserId + uidIterator.next()
148+
Some(lastUserId)
149+
} else {
150+
None
151+
}
152+
153+
val newUserName = if (userNameIterator.hasNext) {
154+
lastUserName = lastUserName + userNameIterator.next()
155+
Some(osmosisStringTable.getString(lastUserName))
156+
} else {
157+
None
158+
}
159+
160+
val info = Info(
161+
version = if (versionIterator.hasNext) Some(versionIterator.next()) else None,
162+
timestamp = newTimestamp,
163+
changeset = newChangeset,
164+
userId = newUserId,
165+
userName = newUserName,
166+
visible = if (visibleIterator.hasNext) Some(visibleIterator.next()) else None
167+
)
168+
169+
Some(info)
170+
}
171+
}
172+
173+
object InfoIterator {
174+
def apply(denseInfo: Option[DenseInfo]): InfoIterator = denseInfo match {
175+
case None => InfoIteratorNone
176+
case Some(info) => new InfoIteratorDeltas(info)
177+
}
178+
}
179+
180+
object InfoIteratorNone extends InfoIterator {
181+
override def next(): Option[Info] = None
182+
override def hasNext: Boolean = true
183+
}
184+
100185
}

core/src/main/scala/com/acervera/osm4scala/model/OSMEntity.scala

-39
This file was deleted.

core/src/main/scala/com/acervera/osm4scala/model/RelationEntity.scala

-59
This file was deleted.

core/src/main/scala/com/acervera/osm4scala/model/RelationMemberEntity.scala

-36
This file was deleted.

0 commit comments

Comments
 (0)