Core Module
This section provides you with additional information to help you accomplish your specific objectives using the core
module of the Location Library.
The core
module contains key interfaces and algorithms for working with location data in general and the road network in particular.
- Geospatial operations and queries
- Operations to manipulate geo- and projected coordinates, line strings, and bounding boxes
- Proximity search to find elements that are close to a given point
- Path matching that takes a sequence of locations recorded by a vehicle (typically GPS positions) and tries to reconstruct the path taken by the vehicle
- Property maps that provide access to the relevant attributes for each vertex or edge.
libraryDependencies ++= Seq(
"com.here.platform.location" %% "location-core" % "0.21.788"
)
<dependencies>
<dependency>
<groupId>com.here.platform.location</groupId>
<artifactId>location-core_${scala.compat.version}</artifactId>
<version>0.21.788</version>
</dependency>
</dependencies>
dependencies {
compile group: 'com.here.platform.location', name: 'location-core_2.12', version:'0.21.788'
}
Data Model Abstractions
The geospatial
sub-package defines the abstractions for geometry types used in the algorithms (Scala-specific).
The following operations abstract the Location Library from the user types:
This allows you to use your own types with the Location Library.
In case you don't have your own type for geocoordinates, coordinates or bounding boxes, the Location Library provides minimal implementations:
For representing simple line strings, using a sequence of GeoCoordinates is supported.
If you want to use your type as an input to the Location Library, you can define as follows:
case class MyPosition(eventId: String, latitude: Double, longitude: Double)
class MyPosition {
MyPosition(final String eventId, final double latitude, final double longitude) {
this.eventId = eventId;
this.latitude = latitude;
this.longitude = longitude;
}
final String eventId;
final double latitude;
final double longitude;
}
Instead of converting the custom input type to the types provided by the Location Library, you can define accessors for your type as follows:
import com.here.platform.location.core.geospatial._
implicit object MyPositionOperations extends GeoCoordinateOperations[MyPosition] {
override def latitude(c: MyPosition): Double = c.latitude
override def longitude(c: MyPosition): Double = c.longitude
}
import com.here.platform.location.core.geospatial.ElementProjection;
import com.here.platform.location.core.geospatial.GeoProjections;
import com.here.platform.location.core.geospatial.javadsl.GeoCoordinateAdapter;
import com.here.platform.location.core.geospatial.javadsl.GeoCoordinates;
import com.here.platform.location.core.geospatial.javadsl.LineStringAdapter;
import com.here.platform.location.core.geospatial.javadsl.LineStrings;
import java.util.Arrays;
import java.util.List;
class MyPositionAdapter implements GeoCoordinateAdapter<MyPosition> {
@Override
public double getLongitude(final MyPosition instance) {
return instance.longitude;
}
@Override
public double getLatitude(final MyPosition instance) {
return instance.latitude;
}
}
Similarly, you can define the required operations for your bounding box or line string type:
case class MyTrip(tripId: String, events: Seq[MyPosition])
implicit object MyTripOperations extends LineStringOperations[MyTrip] {
override type Point = MyPosition
override val PointGeoCoordinateOperations: GeoCoordinateOperations[Point] =
MyPositionOperations
override def points(lineString: MyTrip): Seq[MyPosition] = lineString.events
}
class MyTrip {
String tripId;
List<MyPosition> events;
}
class MyTripAdapter implements LineStringAdapter<MyTrip, MyPosition> {
@Override
public List<MyPosition> getPoints(final MyTrip lineString) {
return lineString.events;
}
}
The following paragraph and the examples demonstrate how to use these abstractions.
Geospatial Operations
After you have implemented the abstractions defined in the previous paragraphs, you can apply various functions to your existing data types with location information.
For example, when computing the compass heading between two WGS-84 coordinates, you can use your custom type:
val start = MyPosition("Start", 52.53062, 13.38531)
val end = MyPosition("End", 52.53088, 13.38515)
println(f"Your heading is: ${GeoCoordinates.heading(start, end)}%1.1f°")
final MyPosition start = new MyPosition("Start", 52.53062, 13.38531);
final MyPosition end = new MyPosition("End", 52.53088, 13.38515);
final double heading = GeoCoordinates.getInstance(new MyPositionAdapter()).heading(start, end);
System.out.format("Your heading is: %1.1f°%n", heading);
Your heading is: 339.5°
Similarly, if you have a segment geometry and want to compute the projection of a point onto that geometry together with the distance, you would use the following code:
import com.here.schema.geometry.v2.geometry.{LineString, Point}
import com.here.platform.location.integration.heremapcontent.geospatial.Implicits._
val geometry: LineString = LineString(
Seq(Point(52.51464, 13.40091),
Point(52.51546, 13.40027),
Point(52.51573, 13.40009),
Point(52.51591, 13.40001)))
val position = MyPosition("Current", 52.51537, 13.40114)
val projection = LineStrings.pointProjection[MyPosition, LineString](
position,
geometry,
SinusoidalProjection
)
println(
"The nearest point is: " +
f"${projection.nearest.latitude}%1.5f, ${projection.nearest.longitude}%1.5f")
final MyTrip geometry = new MyTrip();
geometry.events =
Arrays.asList(
new MyPosition("1", 52.51464, 13.40091),
new MyPosition("2", 52.51546, 13.40027),
new MyPosition("3", 52.51573, 13.40009),
new MyPosition("4", 52.51591, 13.40001));
final MyPosition position = new MyPosition("Current", 52.51537, 13.40114);
final ElementProjection<MyTrip> projection =
LineStrings.getInstance(new MyTripAdapter(), new MyPositionAdapter())
.pointProjection(position, geometry, GeoProjections.sinusoidal());
System.out.format(
"The nearest point is: %1.5f, %1.5f%n",
projection.getNearest().getLatitude(), projection.getNearest().getLongitude());
The projection contains the fraction representing the position of the projected point on the line string as well. You can access this fraction as follows:
val fraction = projection.fraction
println(f"The nearest point is ${fraction * 100}%1.0f%% of the way along the segment")
final double fraction = projection.getFraction();
System.out.format(
"The nearest point is %1.0f%% of the way along the segment%n", fraction * 100);