The purpose of this tutorial is to learn how to look up the Tiles that cover a certain area in a location using the HereTileResolver Java and HereTileResolver Scala classes from the Location Library.
Tiling is a process of dividing map data into partitions. The HERE Tiling scheme is based on a quadtree. A quadtree is a tree data structure in which each internal node has four children.
Quadtree partitions a two-dimensional space by recursively subdividing it into four Tiles. The child Tiles are numbered 0-3 in a fixed reverse S pattern.
Each Tile in the map has an identifier called a HERE Tile ID. A HERE Tile ID is a 64-bit unsigned integer computed from the tile's quadkey. A quadkey is a string of numbers (0-3) that captures the hierarchy of parent-child Tiles from level one to the target Tile level.
For example, for the Tile of level 5 containing San Francisco in the map, the quadkey would be 02123 because the parent Tile is 0212, and the child Tile containing San Francisco is 3. The Tile ID happens to be 1179.
Figure 1. Map
However, you do not need to calculate the Tile IDs yourself. You can lean on the HereTileResolver class to calculate Tile IDs for various area queries. This class is part of the Location Library. In the following chapters, you will create applications to get Tile information using the Tile ID and calculate Tile IDs according to the HERE Tile partitioning scheme.
For more details on HERE tile partitioning, see Partitions.
Set up the Maven project
Download the source code in the beginning of the tutorial and put it in a folder of your choice, or create a folder structure from scratch for your project:
Location Library provides basic methods for retrieving information about a given Tile ID.
The following tutorial demonstrates how to use the HereTileLevel and HereTileResolver classes to get:
Zoom Level for the given Tile ID
BoundingBox for the given Tile ID
using San Francisco Tile ID 19319030.
The following list explains the terminology that occur in this tutorial:
Zoom Level determines how much of the world is visible on a map. Location Library supports a maximum of 31 zoom levels, with 0 being the lowest zoom level (fully zoomed out) and 31 being the highest (fully zoomed in). At lower zoom levels, a smaller set of map Tiles covers a large geographical area. At higher zoom levels, a larger number of Tiles cover a smaller geographical area.
The following picture shows Tiles on 1, 11, and 14 zoom levels:
BoundingBox (usually shortened to bbox) is an area defined by two longitudes and two latitudes, where:
Latitude is a decimal number between -90.0 and 90.0.
Longitude is a decimal number between -180.0 and 180.0.
The picture below shows bbox with coordinates { north : 37.79287, south : 37.68127, east : -122.34480, west : -122.54244 } on the map:
Figure 2. Example of Bounding Boxing with coordinates { north : 37.79287, south : 37.68127, east : -122.34480, west : -122.54244 }
The Location Library provides the following methods to get information for given Tile ID:
apply() from the HereTileLevel class
boundingBoxOf(HereTile tileId) from the HereTileResolver class
With the following code snippet , you can get all information about San Francisco Tile ID 19319030 described above:
Scala
Java
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.BoundingBox
importcom.here.platform.location.inmemory.geospatial.TileId
importcom.here.platform.location.integration.herecommons.geospatial.{
HereTileLevel,
HereTileResolver
}object HereTileInformationTutorialScala {def main(args: Array[String]):Unit={val sanFranciscoTileId = TileId(19319030)val zoomLevel = HereTileLevel.apply(sanFranciscoTileId)
println(s"Zoom Level for Tile ${sanFranciscoTileId.value} is ${zoomLevel.value}")val boundingBox: BoundingBox = HereTileResolver.boundingBoxOf(sanFranciscoTileId)
printf(s"Bounding box for Tile ${sanFranciscoTileId.value} is $boundingBox")}}
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.BoundingBox;importcom.here.platform.location.integration.herecommons.geospatial.HereTileLevel;importcom.here.platform.location.integration.herecommons.geospatial.javadsl.HereTileResolver;publicclassHereTileInformationTutorial{publicstaticvoidmain(String[] args){long sanFranciscoTileId =19319030L;int zoomLevel =HereTileLevel.apply(sanFranciscoTileId).value();System.out.printf("Zoom Level for Tile %s is %s%n", sanFranciscoTileId, zoomLevel);BoundingBox boundingBox =HereTileResolver.boundingBoxOf(sanFranciscoTileId);System.out.printf("Bounding box for Tile %s is %s", sanFranciscoTileId, boundingBox);}}
To execute the application, run the following command:
Zoom Level for Tile 19319030 is 12
Bounding box for Tile 19319030 is BoundingBox(37.79296875,37.705078125,-122.431640625,-122.51953125)
Quad-Tree traversal
Every Tile has one ancestor Tile and one or more descendants.
Ancestor Tile is a Tile at a lower zoom level which has descendant Tiles on the same area of the map with a higher zoom level.
Descendant Tiles are Tiles at a higher zoom level, which are included in the area on the map of the ancestor Tile. The number of descendant Tiles depends on the zoom level. For example, Tile on zoom level n has 4 descendant Tiles on zoom level n+1 and 16 descendant tiles on zoom level n+2.
The following figure shows an ancestor tile on level 12 with the blue border and 16 descendant Tiles on level 14 with the red borders.
Figure 3. Ancestor and descendant Tiles
The HereTileResolver class provides the following methods to get ancestor and descendant Tiles:
fromDescendantTile(descendantTileId) [ Java API | Scala API ] to get an ancestor Tile for the given descendant Tile ID. If the tile is at the highest level, and it has no parents, then the current tile's ID is returned.
fromAncestorTile(ancestorTileId) [ Java API | Scala API ] to get descendant Tiles for given ancestor Tile ID.
Using the following code snippet, you can get descendant tiles on 14 zoom level using San Francisco Tile ID 19319030 on 12 zoom level, and for one of the resulting descendant Tile get ancestor Tile on zoom level 12. The resulting ancestor Tile is a San Francisco Tile ID 19319030 that we passed on to obtain descent Tiles.
Scala
Java
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.inmemory.geospatial.TileId
importcom.here.platform.location.integration.herecommons.geospatial.{
HereTileLevel,
HereTileResolver
}object QuadTreeTraversalTutorialScala {val ZOOM_LEVEL_TWELVE =12val ZOOM_LEVEL_FOURTEEN =14def main(args: Array[String]):Unit={val sanFranciscoTileId =19319030val resolverTwelve: HereTileResolver =new HereTileResolver(HereTileLevel(ZOOM_LEVEL_TWELVE))val resolverFourteen: HereTileResolver =new HereTileResolver(
HereTileLevel(ZOOM_LEVEL_FOURTEEN))val descendantTiles: Set[TileId]=
resolverFourteen.fromAncestorTile(TileId(sanFranciscoTileId))
println(
s"The Tile $sanFranciscoTileId (level $ZOOM_LEVEL_TWELVE) has the following descendant Tiles on level $ZOOM_LEVEL_FOURTEEN: ${descendantTiles.map(_.value).mkString(",")}")val sanFranciscoDescendantTile = descendantTiles.head
val ancestorTile: TileId =
resolverTwelve.fromDescendantTile(sanFranciscoDescendantTile)
println(
s"The tile ${sanFranciscoDescendantTile.value} (level $ZOOM_LEVEL_FOURTEEN) has the following ancestor Tile on level $ZOOM_LEVEL_TWELVE: ${ancestorTile.value}")}}
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.integration.herecommons.geospatial.HereTileLevel;importcom.here.platform.location.integration.herecommons.geospatial.javadsl.HereTileResolver;importjava.util.Set;publicclassQuadTreeTraversalTutorial{publicstaticfinalint ZOOM_LEVEL_TWELVE =12;publicstaticfinalint ZOOM_LEVEL_FOURTEEN =14;publicstaticvoidmain(String[] args){int sanFranciscoTileId =19319030;HereTileResolver resolverTwelve =newHereTileResolver(newHereTileLevel(ZOOM_LEVEL_TWELVE));HereTileResolver resolverFourteen =newHereTileResolver(newHereTileLevel(ZOOM_LEVEL_FOURTEEN));Set<Long> descendantTiles = resolverFourteen.fromAncestorTile(sanFranciscoTileId);System.out.printf("The Tile %s (level %s) has the following descendant Tiles on level %s: %s%n",
sanFranciscoTileId, ZOOM_LEVEL_TWELVE, ZOOM_LEVEL_FOURTEEN, descendantTiles);long sanFranciscoDescendantTile = descendantTiles.stream().findFirst().get();long ancestor = resolverTwelve.fromDescendantTile(sanFranciscoDescendantTile);System.out.printf("The Tile %s (level %s) has the following ancestor Tile on level %s: %s",
sanFranciscoDescendantTile, ZOOM_LEVEL_FOURTEEN, ZOOM_LEVEL_TWELVE, ancestor);}}
To execute the application, run the following command:
The Tile 19319030 (level 12) has the following descendant Tiles on level 14: [309104494, 309104484, 309104489, 309104485, 309104481, 309104493, 309104486, 309104482, 309104492, 309104491, 309104483, 309104487, 309104480, 309104490, 309104495, 309104488]
The Tile 309104494 (level 14) has the following ancestor Tile on level 12: 19319030
Point search
In case you need to get a Tile that includes a specific geocoordinate, use the fromCoordinate(geoCoordinate) method from the Location Library HereTileResolver [ Java API | Scala API ] class.
With the following code snippet, you can get a Tile ID on zoom level 12 that covers Golden Gate Bridge in San Francisco.
Geocoordinate instance is created using Golden Gate Bridge Latitude 37.82171 and Golden Gate Bridge Longitude -122.47881.
Figure 4. Tile that covers Golden Gate Bridge in San Francisco
Scala
Java
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.GeoCoordinate
importcom.here.platform.location.inmemory.geospatial.TileId
importcom.here.platform.location.integration.herecommons.geospatial.{
HereTileLevel,
HereTileResolver
}object HereTileWithPointTutorialScala {val ZOOM_LEVEL_TWELVE =12def main(args: Array[String]):Unit={val goldenGateBrgLatitude =37.82171val goldenGateBrgLongitude =-122.47881val hereTileResolver =new HereTileResolver(HereTileLevel(ZOOM_LEVEL_TWELVE))val geoCoordinateSanFrancisco = GeoCoordinate(goldenGateBrgLatitude, goldenGateBrgLongitude)val tileId = hereTileResolver.fromCoordinate(geoCoordinateSanFrancisco)
println(
s"Tile ${tileId.value} on level $ZOOM_LEVEL_TWELVE containing the point $geoCoordinateSanFrancisco")}}
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.GeoCoordinate;importcom.here.platform.location.integration.herecommons.geospatial.HereTileLevel;importcom.here.platform.location.integration.herecommons.geospatial.javadsl.HereTileResolver;publicclassHereTileWithPointTutorial{publicstaticfinalint ZOOM_LEVEL_TWELVE =12;publicstaticvoidmain(String[] args){double goldenGateBrgLatitude =37.82171;double goldenGateBrgLongitude =-122.47881;HereTileResolver hereTileResolver =newHereTileResolver(newHereTileLevel(ZOOM_LEVEL_TWELVE));GeoCoordinate geoCoordinateSanFrancisco =newGeoCoordinate(goldenGateBrgLatitude, goldenGateBrgLongitude);Long tileId = hereTileResolver.fromCoordinate(geoCoordinateSanFrancisco);System.out.printf("Tile %s on level %s contains the point %s",
tileId, ZOOM_LEVEL_TWELVE, geoCoordinateSanFrancisco);}}
To execute the application, run the following command:
Tile 19319036 on level 12 contains the point GeoCoordinate(37.82171,-122.47881)
Bounding Box search
In the previous tutorial, we learned how to find a Tile for a certain coordinate on the map. This tutorial describes how to find Tiles that cover a certain area on the map. To get Tiles in a certain rectangular part of the map, you should use Bounding Box.
The fromBoundingBox(boundingBox) method in the [ Java API | Scala API ] class, allows you to get Tiles that cover a given bounding box.
The following application uses the Golden Gate Park longitudes and latitudes:
Westbound Longitude = -122.511241
Eastbound Longitude = -122.452919
Southbound Latitude = 37.763901
Northbound Latitude = 37.774723
and returns a set of Tile IDs that cover Golden Gate Park on the zoom level of 15.
The following figure shows a bounding box with a red border and Tiles that cover this bbox with the blue borders.
Figure 5. Tiles that cover `Golder Gate Park` in San Francisco
Scala
Java
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.BoundingBox
importcom.here.platform.location.inmemory.geospatial.TileId
importcom.here.platform.location.integration.herecommons.geospatial.{
HereTileLevel,
HereTileResolver
}object HereBoundingBoxTutorialScala {val ZOOM_LEVEL_FIFTEEN =15def main(args: Array[String]):Unit={val westBoundLongitude =-122.511241val eastBoundLongitude =-122.452919val southBoundLatitude =37.763901val northBoundLatitude =37.774723val hereTileResolver =new HereTileResolver(HereTileLevel(ZOOM_LEVEL_FIFTEEN))val bbox =new BoundingBox(northBoundLatitude,
southBoundLatitude,
eastBoundLongitude,
westBoundLongitude)val tilesCoveringBbox: Set[TileId]= hereTileResolver.fromBoundingBox(bbox)
println(
s"Tiles covering $bbox on level $ZOOM_LEVEL_FIFTEEN are [${tilesCoveringBbox.map(_.value).mkString(",")}]")}}
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.BoundingBox;importcom.here.platform.location.integration.herecommons.geospatial.HereTileLevel;importcom.here.platform.location.integration.herecommons.geospatial.javadsl.HereTileResolver;importjava.util.Set;publicclassHereBoundingBoxTutorial{publicstaticfinalint ZOOM_LEVEL_FIFTEEN =15;publicstaticvoidmain(String[] args){double westBoundLongitude =-122.511241;double eastBoundLongitude =-122.452919;double southBoundLatitude =37.763901;double northBoundLatitude =37.774723;HereTileResolver hereTileResolver =newHereTileResolver(newHereTileLevel(ZOOM_LEVEL_FIFTEEN));BoundingBox bbox =newBoundingBox(
northBoundLatitude, southBoundLatitude, eastBoundLongitude, westBoundLongitude);Set<Long> tilesCoveringBbox = hereTileResolver.fromBoundingBox(bbox);System.out.printf("Tiles covering %s on level %s are %s", bbox, ZOOM_LEVEL_FIFTEEN, tilesCoveringBbox);}}
To execute the application, run the following command:
The previous tutorial demonstrates how to get Tiles in a certain rectangular part of the map. However, the HereTileResolver class provides the fromCenterAndRadius(centerPoint, radius) [ Java API | Scala API ] method that allows you to find Tiles in a certain circle with the specified center and radius in meters. This method can be useful if you do not have the exact coordinates to create a bounding box, but you do have a specific point on the map. In this case, to get all the Tiles that cover this circle, you can specify this point, and the radius in meters.
The following application in both Java and Scala returns Tiles that cover the circle with geocoordinates of Holly Park in San Francisco and radius 150 meters using zoom level 18. Geo Coordinate instance is created using Holly Park Latitude 37.74638 and Holy Park Longitude -122.43584.
The following figure shows a circle with a radius of 150 meters which covers Holy Park and four Tiles that cover this circle.
Figure 6. Tiles that cover `Holly Park` in San Francisco.
Scala
Java
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.GeoCoordinate
importcom.here.platform.location.inmemory.geospatial.TileId
importcom.here.platform.location.integration.herecommons.geospatial.{
HereTileLevel,
HereTileResolver
}object HereTileRadiusSearchScala {val ZOOM_LEVEL_EIGHTEEN =18def main(args: Array[String]):Unit={val sanFranciscoLatitude =37.73721val sanFranciscoLongitude =-122.41994val radiusInMeters =100val hereTileResolver =new HereTileResolver(HereTileLevel(ZOOM_LEVEL_EIGHTEEN))val sanFranciscoGeoCoordinates =new GeoCoordinate(sanFranciscoLatitude, sanFranciscoLongitude)val tilesCoveringCircle: Set[TileId]=
hereTileResolver.fromCenterAndRadius(sanFranciscoGeoCoordinates, radiusInMeters)
println(
s"A circle with a center at $sanFranciscoGeoCoordinates and radius of $radiusInMeters meters covers the following tiles on level $ZOOM_LEVEL_EIGHTEEN: ${tilesCoveringCircle
.map(_.value).mkString(", ")}")}}
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.GeoCoordinate;importcom.here.platform.location.integration.herecommons.geospatial.HereTileLevel;importcom.here.platform.location.integration.herecommons.geospatial.javadsl.HereTileResolver;importjava.util.Set;publicclassHereTileRadiusSearchTutorial{publicstaticfinalint ZOOM_LEVEL_EIGHTEEN =18;publicstaticvoidmain(String[] args){double sanFranciscoLatitude =37.73721;double sanFranciscoLongitude =-122.41994;double radiusInMeters =100;HereTileResolver hereTileResolver =newHereTileResolver(newHereTileLevel(ZOOM_LEVEL_EIGHTEEN));GeoCoordinate geoCoordinateSanFrancisco =newGeoCoordinate(sanFranciscoLatitude, sanFranciscoLongitude);Set<Long> tilesCoveringCircle =
hereTileResolver.fromCenterAndRadius(geoCoordinateSanFrancisco, radiusInMeters);System.out.printf("A circle with a center at %s and radius of %s meters covers the following tiles on level %s: %s",
geoCoordinateSanFrancisco, radiusInMeters, ZOOM_LEVEL_EIGHTEEN, tilesCoveringCircle);}}
To execute the application, run the following command:
A circle with a center at 37.73721,-122.41994 and radius of 100.0 meters covers the following tiles on level 18: [79130751637, 79130751551, 79130751592, 79130751680, 79130751594, 79130751681, 79130751549, 79130751595, 79130751593]
Interfacing with other libraries using the GeoCoordinate Adapter
When working with the HereTileResolver class, you often have to create a GeoCoordinate instance to transfer coordinates on a map as we have done many times in the above code sections. Location Library provides the GeoCoordinate class that implements the GeoCoordinateHolder interface. It is highly recommended to use the GeoCoordinate class from the Location Library, however, if you choose not to, you should consider whether your class implements the GeoCoordinateHolder interface if you want to use the instance of this class to work with Location Library. If your class doesn't implement the GeoCoordinateHolder interface, as in this tutorial - then you need to provide a GeoCoordinateAdapter adapter.
This tutorial uses two custom GeoCoordinateJava and GeoCoordinateScala classes that do not implement GeoCoordinateHolder interface:
Scala
Java
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/caseclass GeoCoordinateScala(latitude:Double, longitude:Double){def getLatitude:Double= latitude
def getLongitude:Double= longitude
}
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/publicclassGeoCoordinateJava{privatedouble latitude;privatedouble longitude;publicGeoCoordinateJava(double latitude,double longitude){this.latitude = latitude;this.longitude = longitude;}publicdoublegetLatitude(){return latitude;}publicdoublegetLongitude(){return longitude;}@OverridepublicStringtoString(){returnString.format("(%s,%s)", latitude, longitude);}}
and two custom GeoCoordinateAdapterJava and GeoCoordinateAdapterScala adapters that implement the GeoCoordinateAdapter adapter from the Location Library:
Scala
Java
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.javadsl.GeoCoordinateAdapter
class GeoCoordinateAdapterScala privateextends GeoCoordinateAdapter[GeoCoordinateScala]{overridedef getLatitude(instance: GeoCoordinateScala):Double= instance.latitude
overridedef getLongitude(instance: GeoCoordinateScala):Double= instance.longitude
}object GeoCoordinateAdapterScala {lazyval getInstance =new GeoCoordinateAdapterScala()}
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.javadsl.GeoCoordinateAdapter;publicclassGeoCoordinateAdapterJavaimplementsGeoCoordinateAdapter<GeoCoordinateJava>{privateGeoCoordinateAdapterJava(){}@OverridepublicdoublegetLatitude(GeoCoordinateJava instance){return instance.getLatitude();}@OverridepublicdoublegetLongitude(GeoCoordinateJava instance){return instance.getLongitude();}publicstaticGeoCoordinateAdapterJavagetInstance(){returnnewGeoCoordinateAdapterJava();}}
The following tutorial demonstrates the same as previous one but with the use of custom GeoCoordinatesJava and GeoCoordinatesScala classes that do not implement GeoCoordinateHolder interface, and custom GeoCoordinateAdapterJava and GeoCoordinateAdapterScala adapters that implement GeoCoordinateAdapter interface.
Scala
Java
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.javadsl.GeoCoordinateAdapter
importcom.here.platform.location.integration.herecommons.geospatial.HereTileLevel
importcom.here.platform.location.integration.herecommons.geospatial.javadsl.HereTileResolver
import java.{lang, util};object HereTileRadiusSearchWithGcAdapterTutorialScala {val ZOOM_LEVEL_EIGHTEEN =18def main(args: Array[String]):Unit={val sanFranciscoLatitude =37.73721val sanFranciscoLongitude =-122.41994val radiusInMeters =100val hereTileResolver =new HereTileResolver(new HereTileLevel(ZOOM_LEVEL_EIGHTEEN))val gca: GeoCoordinateAdapter[GeoCoordinateScala]= GeoCoordinateAdapterScala.getInstance
val geoCoordinateSanFrancisco: GeoCoordinateScala =
GeoCoordinateScala(sanFranciscoLatitude, sanFranciscoLongitude)val tilesCoveringCircle: util.Set[lang.Long]=
hereTileResolver.fromCenterAndRadius(geoCoordinateSanFrancisco, radiusInMeters)(gca)
println(
s"A circle with a center at $geoCoordinateSanFrancisco and radius of $radiusInMeters meters covers the following tiles on level $ZOOM_LEVEL_EIGHTEEN: $tilesCoveringCircle")}}
/*
* Copyright (c) 2018-2023 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/importcom.here.platform.location.core.geospatial.javadsl.GeoCoordinateAdapter;importcom.here.platform.location.integration.herecommons.geospatial.HereTileLevel;importcom.here.platform.location.integration.herecommons.geospatial.javadsl.HereTileResolver;importjava.util.Set;publicclassHereTileRadiusSearchWithGcAdapterTutorial{publicstaticfinalint ZOOM_LEVEL_EIGHTEEN =18;publicstaticvoidmain(String[] args){double sanFranciscoLatitude =37.73721;double sanFranciscoLongitude =-122.41994;double radiusInMeters =100;HereTileResolver hereTileResolver =newHereTileResolver(newHereTileLevel(ZOOM_LEVEL_EIGHTEEN));GeoCoordinateAdapter<GeoCoordinateJava> gca =GeoCoordinateAdapterJava.getInstance();GeoCoordinateJava geoCoordinateSanFrancisco =newGeoCoordinateJava(sanFranciscoLatitude, sanFranciscoLongitude);Set<Long> tilesCoveringCircle =
hereTileResolver.fromCenterAndRadius(geoCoordinateSanFrancisco, radiusInMeters, gca);System.out.printf("A circle with a center at %s and radius of %s meters covers the following tiles on level %s: %s",
geoCoordinateSanFrancisco, radiusInMeters, ZOOM_LEVEL_EIGHTEEN, tilesCoveringCircle);}}
To execute the application, run the following command:
A circle with a center at 37.73721,-122.41994 and radius of 100.0 meters covers the following tiles on level 18: [79130751637, 79130751551, 79130751592, 79130751680, 79130751594, 79130751681, 79130751549, 79130751595, 79130751593]
Further information
For more details on the topics covered in this tutorial, see the following sources:
For more information on the Tile Resolver API in Java, see the API documentation.
For more information on the Tile Resolver Scala in Scala, see the API documentation.
For more information on the different layer types and configurations, see the Data Service documentation.
For more information on how to visualize Tiles on the map using Data Inspector, which was used to create the pictures in this tutorial, see the Data Visualisation Guide