forked from rondiplomatico/nds-tiles
-
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.
edits w.r.t. review on PR rondiplomatico#1
- Loading branch information
Showing
13 changed files
with
872 additions
and
863 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package de.rondiplomatico.nds; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* NDSHashmap allows to store tileY - tileX pairs in a convenient format, | ||
* where tileY is the key and tileX are the value. | ||
* This is convenient because each tileY key has a (sorted) number of tileX value(s) | ||
* and makes several tasks straighforward, such as: | ||
* - drawing a map | ||
* - applying flood-fill algorithm to get map tiles covered by polygon | ||
* - etc. | ||
* | ||
* No warranties for correctness, use at own risk. | ||
* | ||
* @author Andreas Hessenthaler | ||
* @since 28.02.2020 | ||
*/ | ||
public class NDSHashmap { | ||
|
||
/** | ||
* Compute a hash map from tile numbers. | ||
* | ||
* @param level | ||
* the level | ||
* @param tileNumbers | ||
* the tileNumbers | ||
* @return | ||
*/ | ||
public Map<Integer, List<Integer>> tileNumbersToHM(int level, int[] tileNumbers){ | ||
// get the master tile number 0 | ||
NDSTile masterTile = new NDSTile(0, 0); | ||
// create hashmap of (key, value) pairs, where key is tileY and val is tileX | ||
// note: val may contain multiple values | ||
Map<Integer, List<Integer>> tileHM = new HashMap<Integer, List<Integer>>(); | ||
for (int ti = 0; ti < tileNumbers.length; ti++) { | ||
int[] tileXY = masterTile.getTileXYfromTileNumber(level, tileNumbers[ti]); | ||
int key = tileXY[1]; | ||
int newVal = tileXY[0]; | ||
// if key already exists, add value to sorted list; else create new list | ||
if (tileHM.containsKey(key)) { | ||
List<Integer> prevList = tileHM.get(key); | ||
prevList.add(newVal); | ||
Collections.sort(prevList); | ||
tileHM.put(key, prevList); | ||
} else { | ||
List<Integer> newList = new ArrayList<Integer>(); | ||
newList.add(newVal); | ||
tileHM.put(key, newList); | ||
} | ||
} | ||
return tileHM; | ||
} | ||
|
||
/** | ||
* Compute tile numbers from hash map. | ||
* | ||
* @param level | ||
* the level | ||
* @param hm | ||
* the hash map | ||
* @return | ||
*/ | ||
public int[] hmToTileNumbers(int level, Map<Integer, List<Integer>> hm) { | ||
NDSTile masterTile = new NDSTile(0, 0); | ||
int numVals = getNumberOfValuesHM(hm); | ||
int[] filledTileIDs = new int[numVals]; | ||
int idx = 0; | ||
for (Map.Entry<Integer, List<Integer>> entry : hm.entrySet()) { | ||
int key = entry.getKey(); | ||
List<Integer> currList = entry.getValue(); | ||
for (int idx0 = 0; idx0 < currList.size(); idx0++) { | ||
filledTileIDs[idx] = masterTile.getTileNumberFromTileXY(level, currList.get(idx0), key); | ||
idx++; | ||
} | ||
} | ||
return filledTileIDs; | ||
} | ||
|
||
|
||
private int getNumberOfValuesHM(Map<Integer, List<Integer>> hm) { | ||
int numVals = 0; | ||
for (Map.Entry<Integer, List<Integer>> entry : hm.entrySet()) { | ||
numVals = numVals + entry.getValue().size(); | ||
} | ||
return numVals; | ||
} | ||
|
||
} |
105 changes: 105 additions & 0 deletions
105
src/main/java/de/rondiplomatico/nds/NDSPolyFillDemo.java
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,105 @@ | ||
package de.rondiplomatico.nds; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import de.rondiplomatico.nds.NDSUtils; | ||
import de.rondiplomatico.nds.NDSHashmap; | ||
|
||
public class NDSPolyFillDemo { | ||
|
||
/** | ||
* Main method to test selecting all tiles covered by a sample polygon. | ||
* | ||
* @param args | ||
*/ | ||
public static void main(String[] args) { | ||
|
||
long t0 = System.currentTimeMillis(); | ||
|
||
// get some random polygon data for testing purposes | ||
// double[][] polygonCoordinates = new double[][] { | ||
// {10.5, 45.9}, | ||
// {13.0, 50.3}, | ||
// {15.0, 47.0}, | ||
// {13.4, 70.0}, | ||
// {10.5, 45.9} | ||
// }; | ||
|
||
// get some random polygon data for testing purposes | ||
// double[][] polygonCoordinates = new double[][] { | ||
// {10.5, 45.9}, | ||
// {13.0, 63.3}, | ||
// {15.0, 47.0}, | ||
// {13.4, 70.0}, | ||
// {10.5, 45.9} | ||
// }; | ||
|
||
// get some random polygon data for testing purposes | ||
// double[][] polygonCoordinates = new double[][] { | ||
// {10.5, 45.9}, | ||
// {13.0, 50.3}, | ||
// {15.0, 47.0}, | ||
// {17.0, 50.3}, | ||
// {20.0, 47.0}, | ||
// {13.4, 60.0}, | ||
// {13.4, 70.0}, | ||
// {10.5, 45.9} | ||
// }; | ||
|
||
// get some random polygon data approximating Germany | ||
// https://www.mapsofworld.com/lat_long/germany-lat-long.html | ||
double[][] polygonCoordinates = new double[][] { | ||
{10.5, 45.9}, | ||
{13.0, 45.9}, | ||
{14.0, 49.0}, | ||
{12.0, 50.0}, | ||
{15.0, 51.0}, | ||
{15.0, 54.0}, | ||
{13.5, 54.5}, | ||
{11.0, 54.0}, | ||
{10.0, 55.0}, | ||
{ 8.5, 55.0}, | ||
{ 9.0, 54.0}, | ||
{ 7.0, 53.5}, | ||
{ 6.0, 52.0}, | ||
{ 6.1, 50.0}, | ||
{ 8.0, 49.0}, | ||
{ 7.5, 47.5}, | ||
{10.5, 45.9} | ||
}; | ||
|
||
// number of levels in map hierarchy | ||
int maxLevels = 15; | ||
// get a bounding octagonal envelope (defaults to quadrilateral in 2D case) | ||
// for sample data corresponding to a polygon (e.g. borders of a country) | ||
NDSEnvelope envelope = new NDSEnvelope(polygonCoordinates); | ||
// get corresponding bounding tile ID, i.e. find level where all polygon points are on the same tile | ||
int[] masterTileInfo = envelope.getMasterTileInfo(maxLevels); | ||
int masterTileLevel = masterTileInfo[0]; | ||
int masterTileID = masterTileInfo[1]; | ||
// store the master tile | ||
NDSTile masterTile = new NDSTile(masterTileLevel, masterTileID); | ||
// get all tiles covered by the polygon on the tstLevel | ||
int tstLevel = 11; | ||
// refine polygon coordinates to avoid edges that are crossing a tile | ||
// set refinement factor to -1 to adaptively refine | ||
int numSamples = -1; | ||
double[][] polygonCoordinatesRef = NDSPolygon.refinePolygon(tstLevel, polygonCoordinates, numSamples); | ||
// let's grab all tiles with polygon points | ||
int[] uniqueTileIDs = NDSPolygon.getUniqueTileNumbersOnLevel(tstLevel, polygonCoordinatesRef); | ||
// dump to image file for debugging | ||
NDSUtils.printMap(masterTile, tstLevel, uniqueTileIDs, "png", "map"); | ||
// get x/y tile indices for tiles with polygon points | ||
// key is tileY, val is tileX (note: val may contain multiple tileX indices) | ||
NDSHashmap hm = new NDSHashmap(); | ||
Map<Integer, List<Integer>> tileHM = hm.tileNumbersToHM(tstLevel, uniqueTileIDs); | ||
// dump to image file for debugging | ||
Map<Integer, List<Integer>> filledTileHM = NDSPolygon.mapFillPolygon(tileHM, uniqueTileIDs); | ||
int[] filledTileIDs = hm.hmToTileNumbers(tstLevel, filledTileHM); | ||
NDSUtils.printMap(masterTile, tstLevel, filledTileIDs, "png", "mapFilled"); | ||
|
||
long t1 = System.currentTimeMillis(); | ||
System.out.println("\n>>>INFO: Program finished in "+(t1-t0)+" ms."); | ||
} | ||
} |
Oops, something went wrong.