Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IllegalArgumentException caused by historic data for ways #423

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Switched from `osm4scala` to `openstreetmap.osmosis` [#409](https://github.com/ie3-institute/OSMoGrid/issues/409)
- Changed transformer input parameter to PSDM requirements [#417](https://github.com/ie3-institute/OSMoGrid/issues/417)
- Adapted run initialization [#404](https://github.com/ie3-institute/OSMoGrid/issues/404)
- Only consider newest version of `Ways` [#422](https://github.com/ie3-institute/OSMoGrid/issues/422)

### Fixed
- Fixed bug in `LvGridGeneratorSupport` [#388](https://github.com/ie3-institute/OSMoGrid/issues/388)
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/edu/ie3/osmogrid/io/input/ReaderSink.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

package edu.ie3.osmogrid.io.input

import edu.ie3.osmogrid.exception.{InputDataException, PbfReadFailedException}
import edu.ie3.osmogrid.exception.PbfReadFailedException
import edu.ie3.osmogrid.model.OsmoGridModel.LvOsmoGridModel
import edu.ie3.osmogrid.model.{OsmoGridModel, SourceFilter}
import edu.ie3.util.osm.model.OsmContainer.ParOsmContainer
Expand Down
59 changes: 54 additions & 5 deletions src/main/scala/edu/ie3/osmogrid/model/OsmoGridModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,29 @@
}
(matchedEntities.par, matchedSubentities)
}

def filterForWays(
entities: ParSeq[EnhancedOsmEntity]
): (ParSeq[Way], Map[Long, Node]) =
filterForOsmType[Way, Node](entities)
): (ParSeq[Way], Map[Long, Node]) = {
val (matchedEntities, matchedSubentities) =
filterForOsmType[Way, Node](entities)
val (latestEntities, latestNodes) =
filterForLatestVersions(matchedEntities, matchedSubentities)

val ways = latestEntities.collect { case way: Way => way }
(ways, latestNodes)
}

def filterForClosedWays(
entities: ParSeq[EnhancedOsmEntity]
): (ParSeq[ClosedWay], Map[Long, Node]) =
filterForOsmType[ClosedWay, Node](entities)
): (ParSeq[ClosedWay], Map[Long, Node]) = {
val (matchedEntities, matchedSubentities) =
filterForOsmType[ClosedWay, Node](entities)
val (latestEntities, latestNodes) =
filterForLatestVersions(matchedEntities, matchedSubentities)

val closedWays = latestEntities.collect { case way: ClosedWay => way }
(closedWays, latestNodes)
}

def filterForOsmType[E <: OsmEntity: ClassTag, S <: OsmEntity: ClassTag](
entities: ParSeq[EnhancedOsmEntity]
Expand Down Expand Up @@ -93,6 +106,42 @@
(matchedEntities.par, matchedSubentities)
}

def filterForLatestVersions[

Check warning on line 109 in src/main/scala/edu/ie3/osmogrid/model/OsmoGridModel.scala

View check run for this annotation

SonarQubeGithubPRChecks / OSMoGrid Sonarqube Results

src/main/scala/edu/ie3/osmogrid/model/OsmoGridModel.scala#L109

Unused parameter
E <: OsmEntity: ClassTag,
S <: OsmEntity: ClassTag
](entities: ParSeq[E], nodes: Map[Long, S]): (ParSeq[E], Map[Long, S]) = {

val groupedEntities = entities.groupBy(_.id)

val latestEntities = groupedEntities.values
.flatMap { entities =>
val maxVersion = entities
.flatMap {
case entity: E if entity.metaInformation.isDefined =>
entity.metaInformation.map(_.version.getOrElse(0))
case _ => Some(0)
}
.reduceOption(_ max _)
.getOrElse(0)
entities.filter {
case entity: E if entity.metaInformation.isDefined =>
entity.metaInformation.exists(_.version.contains(maxVersion))
case _ => true
}
Copy link
Member

@staudtMarius staudtMarius May 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work if we have two versions of the same entity one with metaInformation and one without?
I think in this case, both versions are returned, which could cause problems. Maybe you could add a test for this case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! I changed this into a logger warning and filter out these entities.

Copy link
Member

@staudtMarius staudtMarius May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we have an entity that occures only once but have no metaInformation? Will it be filtered out too? I think this could cause a porblem when generating grids?

Maybe you could count the occurences of all enitity ids and only use this filter for those entites that have multiple occurences.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I checked there is always a version at the entity. So imho this is very unlikely. But sure we can split the entities and filter only those with multiple occurences. :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, there are of course options to exclude the metainformation. Maybe we should think about to make them mandatory. Will discuss this tomorrow within the sprint :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danielfeismann Do you have an update on this part?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, OSM data that includes multiple versions of the same entity is just broken to me. I'd be fine with just assuming that the OSM data we're handling is coherent. Do we really need the meta information then?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you, @sebastian-peter. Tried it again by using overpass, worked well at that location. So I'm fine with closing this one.

}
.toSeq
.par

val nodeIds = latestEntities.flatMap {
case entity: Way => entity.nodes
case _ => Seq.empty
}.toSet

val latestNodes = nodes.view.filterKeys(nodeIds).toMap

(latestEntities, latestNodes)
}

final case class LvOsmoGridModel(
buildings: ParSeq[EnhancedOsmEntity],
highways: ParSeq[EnhancedOsmEntity],
Expand Down
18 changes: 17 additions & 1 deletion src/test/scala/edu/ie3/osmogrid/model/OsmTestData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ trait OsmTestData {
val highway2Node1: Node = highway1Node2
val highway2Node2: Node =
Node(23L, 50.538d, 7.4065d, Map.empty[String, String], None)
val highway2Node2b: Node =
Node(123L, 50.5382d, 7.40652d, Map.empty[String, String], None)
val highway2Node3: Node =
Node(24L, 50.578d, 7.4265d, Map.empty[String, String], None)
val highway2Node4: Node = highway1Node1
Expand Down Expand Up @@ -199,7 +201,21 @@ trait OsmTestData {
nodes.highway2Node4.id
),
Map("highway" -> "motorway"),
None
Some(OsmEntity.MetaInformation(Some(1), None, None, None, None, None))
)

val highway2oldVersion: OpenWay =
OpenWay(
112L,
Seq(
nodes.highway2Node1.id,
nodes.highway2Node2.id,
nodes.highway2Node2b.id,
nodes.highway2Node3.id,
nodes.highway2Node4.id
),
Map("highway" -> "motorway"),
Some(OsmEntity.MetaInformation(Some(0), None, None, None, None, None))
)

val landuse1: ClosedWay = ClosedWay(
Expand Down
81 changes: 81 additions & 0 deletions src/test/scala/edu/ie3/osmogrid/model/OsmoGridModelSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import edu.ie3.osmogrid.model.SourceFilter.{Filter, LvFilter}
import edu.ie3.test.common.UnitSpec
import edu.ie3.util.osm.model.OsmContainer.ParOsmContainer
import edu.ie3.util.osm.model.OsmEntity.Relation
import edu.ie3.util.osm.model.OsmEntity.Way.{ClosedWay, OpenWay}

import scala.collection.parallel.CollectionConverters._
import scala.collection.parallel.ParSeq

Expand Down Expand Up @@ -403,5 +405,84 @@ class OsmoGridModelSpec extends UnitSpec with OsmTestData {
) shouldBe nodes.building1Node1

}

"filter for correct version of way" in {
val relation = EnhancedOsmEntity(
relations.boundary,
Map(nodes.boundaryNode1.id -> nodes.boundaryNode1)
)

val building = EnhancedOsmEntity(
ways.building1,
Map(nodes.building1Node1.id -> nodes.building1Node1)
)

val highway2 = EnhancedOsmEntity(
ways.highway2,
Map(
nodes.highway2Node1.id -> nodes.highway2Node1,
nodes.highway2Node2.id -> nodes.highway2Node2,
nodes.highway2Node3.id -> nodes.highway2Node3,
nodes.highway2Node4.id -> nodes.highway2Node4
)
)
val highway2oldVersion = EnhancedOsmEntity(
ways.highway2oldVersion,
Map(
nodes.highway2Node1.id -> nodes.highway2Node1,
nodes.highway2Node2.id -> nodes.highway2Node2,
nodes.highway2Node2b.id -> nodes.highway2Node2b,
nodes.highway2Node3.id -> nodes.highway2Node3,
nodes.highway2Node4.id -> nodes.highway2Node4
)
)

val input = ParSeq(
relation,
building,
highway2,
highway2oldVersion
)

val (resultWays, resultWayNodes) =
OsmoGridModel.filterForWays(input)

resultWays.size shouldBe 2

val closedWays = resultWays.collect { case way: ClosedWay => way }
val openWays = resultWays.collect { case way: OpenWay => way }

closedWays.size shouldBe 1
openWays.size shouldBe 1

closedWays.headOption.getOrElse(
fail("No closed way found")
) shouldBe ways.building1
openWays.headOption.getOrElse(
fail("No open way found")
) shouldBe ways.highway2

resultWayNodes.size shouldBe 5
resultWayNodes.getOrElse(
nodes.building1Node1.id,
fail("Collection shouldn't be empty")
) shouldBe nodes.building1Node1

val expectedNodes = List(
nodes.highway2Node1,
nodes.highway2Node2,
nodes.highway2Node3,
nodes.highway2Node4,
nodes.building1Node1
)

expectedNodes.foreach { node =>
resultWayNodes.getOrElse(node.id, fail("Node not found")) shouldBe node
}

resultWayNodes.foreach { case (_, node) =>
expectedNodes should contain(node)
}
}
}
}
3 changes: 2 additions & 1 deletion src/test/scala/edu/ie3/test/common/OsmTestData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package edu.ie3.test.common

import edu.ie3.util.osm.model.OsmEntity
import edu.ie3.util.osm.model.OsmEntity.{Node, Way}

trait OsmTestData {
Expand Down Expand Up @@ -41,7 +42,7 @@ trait OsmTestData {
id,
Seq(nodeA.id, nodeB.id),
Map.empty,
None
Some(OsmEntity.MetaInformation(Some(0)))
)
}
}