forked from Scottish-Tech-Army/Soundscape-Android
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split MVT to GeoJSON translation into separate files and add GeoEngin…
…e Configuration The GeoEngine configuration contains the grid size and zoom levels along with the servers. This used to be hidden away in TileGridUtils.kt which wasn't the best place for it.
- Loading branch information
Showing
12 changed files
with
558 additions
and
525 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
app/src/main/java/org/scottishtecharmy/soundscape/geoengine/Configuration.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.scottishtecharmy.soundscape.geoengine | ||
|
||
/** | ||
* This file contains the various configuration options for the GeoEngine. | ||
*/ | ||
|
||
/** | ||
* The zoom level and grid size are constant. When using soundscape-backend these will be | ||
* 16 and 3, but if we switch to using protobuf tiles they will be 15 and 2. | ||
*/ | ||
const val SOUNDSCAPE_TILE_BACKEND = false | ||
val ZOOM_LEVEL = if(SOUNDSCAPE_TILE_BACKEND) 16 else 15 | ||
var GRID_SIZE = if(SOUNDSCAPE_TILE_BACKEND) 3 else 2 | ||
|
||
/** | ||
* The default tile server is the one out in the cloud where the tile JSON is at: | ||
* https://server/protomaps.json | ||
* | ||
* and the tiles are at | ||
* https://server/protomaps/{z}/{x}/{y}.mvt | ||
*/ | ||
const val PROTOMAPS_SERVER_BASE = "https://d1wzlzgah5gfol.cloudfront.net" | ||
const val PROTOMAPS_SERVER_PATH = "protomaps" | ||
const val PROTOMAPS_SUFFIX = "mvt" | ||
|
||
/** | ||
* It's also useful to be able to use tiles served up locally when testing. When I | ||
* test locally I'm serving up the file like this: | ||
* | ||
* tileserver-gl-light --file europe.pmtiles -b 192.168.86.39 | ||
* | ||
* With this configuration the tile JSON descriptor appears at: | ||
* http://192.168.86.39:8080/data/v3.json | ||
* | ||
* and the tiles within it are at: | ||
* http://192.168.86.39:8080/data/v3/{z}/{x}/{y}.pbf | ||
* | ||
*/ | ||
//const val PROTOMAPS_SERVER_BASE = "http://192.168.86.39:8080" | ||
//const val PROTOMAPS_SERVER_PATH = "data/v3" | ||
//const val PROTOMAPS_SUFFIX = "pbf" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
...rc/main/java/org/scottishtecharmy/soundscape/geoengine/mvttranslation/EntranceMatching.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package org.scottishtecharmy.soundscape.geoengine.mvttranslation | ||
|
||
import org.scottishtecharmy.soundscape.geojsonparser.geojson.Feature | ||
import org.scottishtecharmy.soundscape.geojsonparser.geojson.FeatureCollection | ||
import org.scottishtecharmy.soundscape.geojsonparser.geojson.Point | ||
|
||
class EntranceMatching { | ||
|
||
/** | ||
* buildingNodes is a sparse map which maps from a location within the tile to a list of | ||
* building polygons which have nodes at that point. Every node on any `POI` polygon will appear | ||
* in the map along with any entrance. After processing it should be straightforward to match | ||
* up entrances to their POI polygons. | ||
*/ | ||
private val buildingNodes : HashMap< Int, ArrayList<EntranceDetails>> = hashMapOf() | ||
|
||
/** | ||
* addLine is called for any line feature that is being added to the FeatureCollection. | ||
* @param line is a new `transportation` layer line to add to the map | ||
* @param details describes the line that is being added. | ||
* | ||
*/ | ||
fun addPolygon(line : ArrayList<Pair<Int, Int>>, | ||
details : EntranceDetails | ||
) { | ||
for (point in line) { | ||
if((point.first < 0) || (point.first > 4095) || | ||
(point.second < 0) || (point.second > 4095)) { | ||
continue | ||
} | ||
|
||
// Rather than have a 2D sparse array, turn the coordinates into a single int so that we | ||
// can have a 1D sparse array instead. | ||
val coordinateKey = point.first.shl(12) + point.second | ||
if (buildingNodes[coordinateKey] == null) { | ||
buildingNodes[coordinateKey] = arrayListOf(details.copy()) | ||
} | ||
else { | ||
buildingNodes[coordinateKey]?.add(details.copy()) | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* generateIntersections goes through our hash map and adds an intersection feature to the | ||
* collection wherever it finds out. | ||
* @param collection is where the new intersection features are added | ||
* @param tileX the tile x coordinate so that the tile relative location of the intersection can | ||
* be turned into a latitude/longitude | ||
* @param tileY the tile y coordinate so that the tile relative location of the intersection can | ||
* * be turned into a latitude/longitude | ||
*/ | ||
fun generateEntrances(collection: FeatureCollection, tileX : Int, tileY : Int, tileZoom : Int) { | ||
// Add points for the intersections that we found | ||
for ((key, nodes) in buildingNodes) { | ||
|
||
// Generate an entrance with a matching POI polygon | ||
var entranceDetails : EntranceDetails? = null | ||
var poiDetails : EntranceDetails? = null | ||
for(node in nodes) { | ||
if(!node.poi) { | ||
// We have an entrance! | ||
entranceDetails = node | ||
} else { | ||
poiDetails = node | ||
} | ||
} | ||
|
||
// If we have an entrance at this point then we generate a feature to represent it | ||
// using the POI that it is coincident with if there is one. | ||
if(entranceDetails != null) { | ||
// Turn our coordinate key back into tile relative x,y coordinates | ||
val x = key.shr(12) | ||
val y = key.and(0xfff) | ||
// Convert the tile relative coordinate into a LatLngAlt | ||
val point = arrayListOf(Pair(x, y)) | ||
val coordinates = convertGeometry(tileX, tileY, tileZoom, point) | ||
|
||
// Create our entrance feature to match those from soundscape-backend | ||
val entrance = Feature() | ||
entrance.geometry = | ||
Point(coordinates[0].longitude, coordinates[0].latitude) | ||
entrance.foreign = HashMap() | ||
entrance.foreign!!["feature_type"] = "entrance" | ||
entrance.foreign!!["feature_value"] = entranceDetails.entranceType | ||
val osmIds = arrayListOf<Double>() | ||
osmIds.add(entranceDetails.osmId) | ||
entrance.foreign!!["osm_ids"] = osmIds | ||
|
||
entrance.properties = HashMap() | ||
entrance.properties!!["name"] = entranceDetails.name | ||
if(entranceDetails.name == null) | ||
entrance.properties!!["name"] = poiDetails?.name | ||
|
||
collection.addFeature(entrance) | ||
|
||
// println("Entrance: ${poiDetails?.name} ${entranceDetails.entranceType} ") | ||
} | ||
} | ||
} | ||
} | ||
|
||
data class EntranceDetails( | ||
val name : String?, | ||
val entranceType : String?, | ||
val poi: Boolean, | ||
val osmId : Double, | ||
) |
Oops, something went wrong.